# -*- coding: utf-8 -*-
__author__ = 'xuliliang'
# @Time    : 2018/1/11 上午11:17
# @Author  : 'xuliliang'
# @Email   : xuliliang@u51.com
# @File    : saltapi.py
# @Software: PyCharm

import urllib2
import urllib
import json
# from  django.conf import  settings


class SaltApi():
    token_id = ''

    def __init__(self):
        # self.url = settings.SALT_API_URL
        # self.username = settings.SALT_API_USER
        # self.password = settings.SALT_API_PASSWD
        self.url = 'http://10.1.126.23:8000'
        self.username = 'saltapi'
        self.password = 'saltapi'


# 定义请求的方式


    def postRequest(self, obj, prefix='/'):
        url = self.url + prefix
        headers = {'X-Auth-Token': self.token_id}
        req = urllib2.Request(url, obj, headers=headers)
        opener = urllib2.urlopen(req)
        content = json.loads(opener.read())
        return content

    def get_token_id(self):
        '''
        获取salt-api的tokenID
        '''
        data = {
            'username': self.username,
            'password': self.password,
            'eauth': 'pam',
        }
        obj = urllib.urlencode(data)
        content = self.postRequest(obj, prefix='/login')
        try:
            self.token_id = content['return'][0]['token']
        except KeyError:
            raise ValueError
        return self.token_id

    def list_all_key(self):
        '''
        获取包括认证的minions
        curl -k http://10.1.0.23:8000 -H "Accept: application/json"      -H "X-Auth-Token: a4c9875004b2543da8f8072f76ad3de105e889b0"    -d client='wheel' -d tgt='*' -d fun='key.list_all'
        '''
        params = {'client': 'wheel', 'fun': 'key.list_all'}
        self.get_token_id()
        obj = urllib.urlencode(params)
        content = self.postRequest(obj)
        # keys_list  = content['return'][0]['data']['return']['minions']
        keys_list = content['return'][0]['data']['return']
        return keys_list

    def salt_command(self, tgt, method, arg=None):
        '''同步执行命令
        '''
        if arg:
            params = {'client': 'local', 'fun': method, 'tgt': tgt, 'arg': arg}
        else:
            params = {'client': 'local', 'fun': method, 'tgt': tgt}
        print '命令参数: ', params
        self.get_token_id()
        obj = urllib.urlencode(params)
        content = self.postRequest(obj)
        return content

    def async_deploy(self, tgt, method, arg=None):
        '''异步执行远程命令
        '''
        if arg:
            params = {'client': 'local_async',
                      'fun': method, 'tgt': tgt, 'arg': arg}
        else:
            params = {'client': 'local_async', 'fun': method, 'tgt': tgt}
        self.get_token_id()
        obj = urllib.urlencode(params)
        content = self.postRequest(obj)
        jid = content['return'][0]['jid']
        return jid

    def look_jid(self, jid):  # 根据异步执行命令返回的jid查看事件结果
        params = {'client': 'runner', 'fun': 'jobs.lookup_jid', 'jid': jid}
        self.get_token_id()
        obj = urllib.urlencode(params)
        content = self.postRequest(obj)
        return content

    def accept_key(self, node_name):
        ''' 接受salt主机
        '''
        params = {'client': 'wheel', 'fun': 'key.accept', 'match': node_name}
        obj = urllib.urlencode(params)
        self.get_token_id()
        content = self.postRequest(obj)
        ret = content['return'][0]['data']['success']
        return ret

    def delete_key(self, node_name):
        ''' 删除所有keys'''
        params = {'client': 'wheel', 'fun': 'key.delete', 'match': node_name}
        obj = urllib.urlencode(params)
        self.get_token_id()
        content = self.postRequest(obj)
        ret = content['return'][0]['data']['success']
        return ret

    def file_backup(self):
        params = {'client': 'client', 'fun': 'file.managed', }

    def get_minions_grains(self, minion):
        url = self.url + '/' + 'minions' + '/' + minion
        token = self.get_token_id()
        headers = {'X-Auth-Token': token}
        req = urllib2.Request(url, headers=headers)
        res = urllib2.urlopen(req)
        content = json.loads(res.read())
        content = content['return'][0][minion]
        return content

        # curl -k http://10.1.126.23:8000/minions/10.1.126.14 -H "Accept: application/json"      -H "X-Auth-Token: 306e89bb13849a42e2e2d87391da49c5863dceb0"

    def file_upload(self, tgt, fun, file_src, file_dest, expr_form):
        '''
        文件上传,arg多次重复参数会导致这些参数被合并到一个列表中,需要单独拼接arg参数
        makedirs=True 目录不存在则创建目录
        '''
        params = {'client': 'local', 'tgt': tgt, 'fun': fun, 'arg': file_src}
        params2 = {'arg': file_dest}
        params3 = {'arg': expr_form}
        arg_add = urllib.urlencode(params2)
        arg_add2 = urllib.urlencode(params3)
        obj = urllib.urlencode(params)
        obj = obj + '&' + arg_add + '&' + arg_add2
        self.get_token_id()
        content = self.postRequest(obj)
        print content
        ret = content['return'][0]
        # print  ret
        return ret

    def runner_status(self, arg):
        ''' Return minion status '''
        params = {'client': 'runner', 'fun': 'manage.' + arg}
        self.get_token_id()
        obj = urllib.urlencode(params)
        content = self.postRequest(obj)

        jid = content['return'][0]
        return jid


def main():
    sapi = SaltApi()
    # sapi.get_token_id()
    # sapi.list_all_key()
    # status = sapi.runner_status('status')['up']
    # print  status
    # sapi.accept_key('10.1.0.18')
    sapi.file_upload('10.1.126.22', 'cp.get_file',
                     'salt://test.sls', '/tmp/test.sls', 'makedirs=True')

    # cp.push 模块允许minion上传文件到master端，上传的文件存放在master端的 /var/cache/salt/master/minions//files/ 目录下
    # cp.get_file用于minion从master下载文件
    # as_exec = sapi.salt_command('10.1.0.22', 'cp.push', '/tmp/22.log')
    # print  as_exec
    # sapi.look_jid(as_exec)
    # print  res2
    # sapi.get_minions_grains('10.1.126.22')

    # print  "同步执行================================"
    # salt_client = '10.1.0.22' #
    # salt_test = 'test.ping'
    # salt_method = 'cmd.run'
    # salt_params = 'uptime'
    # result1 = sapi.salt_command(salt_client, salt_test)
    # for i in result1.keys():
    #     print i, ': ', result1[i]
    # result2 = sapi.salt_command(salt_client, salt_method, salt_params)
    # for i in result2.keys():
    #     # print i
    #     print result2[i]

    # print  "异步执行==============================="
    # salt_test = 'test.ping'
    # salt_client = '*'
    # salt_method = 'cmd.run'
    # salt_params = 'uptime'
    # jid2 = sapi.async_deploy(salt_client, salt_method, salt_params)
    # # jid2 = sapi.async_deploy('10.1.0.22', cmd.run, 'uptime')
    # result2 = sapi.look_jid(jid2)
    # for i in result2.keys():
    #     print i
    #     print result2[i]


if __name__ == '__main__':
    main()
